package com.sdp.wx.controller;


import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.sdp.core.bizc.db.Query;
import com.sdp.core.bizc.utils.ApplicationContextUtils;
import com.sdp.core.bizc.utils.UniqueCheckTools;
import com.sdp.core.bizc.vo.BusinessContext;
import com.sdp.core.bizc.vo.DataCenter;
import com.sdp.core.bizc.vo.Result;
import com.sdp.flow.db.entity.ActHiComment;
import com.sdp.flow.db.service.IWorkflowService;
import com.sdp.flow.dto.FlowParam;
import com.sdp.flow.utils.FlowConstants;
import com.sdp.wx.db.wx_wz_procured.entity.WxWzProcured;
import com.sdp.wx.db.wx_wz_procured.service.IWxWzProcuredService;
import com.sdp.wx.db.wx_wz_procured_detail.entity.WxWzProcuredDetail;
import com.sdp.wx.db.wx_wz_procured_detail.service.IWxWzProcuredDetailService;
import com.sdp.wx.utils.CurrentLoginEmp;
import com.sdp.wx.utils.WxConstants;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author zsp
 * @since 2024-01-20
 */
@RestController
@RequestMapping("/WxWzProcuredController")
public class WxWzProcuredController {

	@Autowired
	private IWxWzProcuredService iWxWzProcuredService;
	
	@Autowired
	private Query query;
	
	@Autowired
	private UniqueCheckTools uniqueCheckTools;
	
	@Autowired
	private CurrentLoginEmp currentLoginEmp;
	
	@Autowired
	private IWorkflowService workflowService;
	
	@Autowired
	private WxRepairCodeController wxRepairCodeController;
	
	@Autowired
	private IWxWzProcuredDetailService iWxWzProcuredDetailService;
	
	@PostMapping(value = "/page")
	public Result<?> page(@RequestBody DataCenter dataCenter) {
		return Result.ok(query.page(iWxWzProcuredService, WxWzProcured.class, dataCenter));
	}
	
	@PostMapping(value = "/save")
	@Transactional(rollbackFor=Exception.class)
	public Result<?> save(@RequestBody JSONObject obj) {
	
		if(obj==null || obj.get("formData")==null){
			return Result.error("器材采购信息为空");
		}
		
		List<WxWzProcuredDetail> wzList = JSONArray.parseArray(JSON.toJSONString(obj.get("wzList")), WxWzProcuredDetail.class);
		WxWzProcured wzProcured = JSONObject.parseObject(JSON.toJSONString(obj.get("formData")), WxWzProcured.class);
		
		String planCode = wxRepairCodeController.createRepairCode(WxConstants.流水号类型_器材采购单.getCode(),WxConstants.流水号前缀_器材采购单.getCode());
		if(StringUtils.isEmpty(planCode)) {
			return Result.error("采购计划编号生成出现错误");
		}
		JSONObject emp = currentLoginEmp.getCurrentLoginInfo();
		if(StringUtils.isEmpty(wzProcured.getKeyId())) {
			if(StringUtils.isEmpty(wzProcured.getPlanName())) {
				wzProcured.setPlanName(planCode);
			}
			Result<?> r = uniqueCheckTools.isUniqueSingle(iWxWzProcuredService, WxWzProcured.class, new String[] {"planName"}, "keyId", wzProcured, null, false);
			if(r==null || !r.isSuccess()) {
				return Result.error("采购计划名不能重复");
			}

			wzProcured.setPlanCode(planCode);
			wzProcured.setCreateTime(LocalDateTime.now());
			wzProcured.setApprovalState(WxConstants.流程审批状态_未提交.getCode());
			wzProcured.setApplicationEmpNo(emp.getString("empNo"));
			wzProcured.setApplicationEmpName(emp.getString("empName"));
			wzProcured.setIsArrival(WxConstants.否.getCode());
			iWxWzProcuredService.save(wzProcured);
		}else {
			Result<?> r = uniqueCheckTools.isUniqueSingle(iWxWzProcuredService, WxWzProcured.class, new String[] {"planName"}, "keyId", null, wzProcured, false);
			if(r==null || !r.isSuccess()) {
				return Result.error("采购计划名称不能重复");
			}
			iWxWzProcuredService.updateById(wzProcured);
		}
		
		if(wzList!=null && wzList.size()>0) {
			iWxWzProcuredDetailService.updateBatchById(wzList);
		}
		
		return Result.ok(wzProcured);
	}
	
	
	@PostMapping(value = "/saveAndStartFlow")
	@Transactional(rollbackFor=Exception.class)
	public Result<?> saveAndStartFlow(@RequestBody JSONObject obj) {
		if(obj==null || obj.get("formData")==null || obj.get("wzList")==null){
			return Result.error("器材采购信息为空");
		}
	
		Result<?> r = ApplicationContextUtils.getBean(WxWzProcuredController.class).save(obj);
		if(r==null || !r.isSuccess()) {
			return r;
		}
		WxWzProcured wzProcured = (WxWzProcured) r.getResult();
		JSONObject emp = currentLoginEmp.getCurrentLoginInfo();
		wzProcured.setTemplateId(WxConstants.器材采购审批流程模板.getCode());
		//设置审批状态
		wzProcured.setApprovalState(WxConstants.流程审批状态_审批中.getCode());
		
		//发起流程
		FlowParam flowParam = new FlowParam();
		flowParam.setUserId(emp.getString("empNo"));
		flowParam.setTemplateId(wzProcured.getTemplateId());
		flowParam.setBizId(wzProcured.getKeyId());
		
		//指定审批人
		Map<String, Object> variableMap = new HashMap<>();
		BusinessContext businessContext = new BusinessContext();
		businessContext.put(WxWzProcured.class, wzProcured);
		variableMap.put(FlowConstants.FLOW_ASSIGN_PERSON_KEY, wzProcured.getApprover());
		variableMap.put(WxConstants.流程监听器中执行的类.getCode(), "com.sdp.wx.controller.WxWzProcuredController");
		variableMap.put(WxConstants.流程监听器中执行类的方法.getCode(), "flowCommitListener");
		variableMap.put(WxConstants.流程监听器中执行类的方法的参数.getCode(), businessContext);
		flowParam.setVariableMap(variableMap);
		
		
		String instanceId = workflowService.startFlowAndCommit(flowParam);
		if (StringUtils.isEmpty(instanceId)) {
			return Result.error("流程启动失败!");
		}
		
		//发起成功设置流程实例Id
		wzProcured.setInstanceId(instanceId);
		iWxWzProcuredService.updateById(wzProcured);
		return Result.ok(wzProcured);
		
		
	}
	
	/**
	 * 流程提交
	 * @param contract
	 * @return
	 */
	@PostMapping(value = "/commit")
	@Transactional(rollbackFor=Exception.class)
	public Result<?> commit(@RequestBody WxWzProcured procured) {
		if(procured == null) {
			return Result.error("采购信息为空");
		}
		if (StringUtils.isEmpty(procured.getKeyId())) {
			return Result.error("采购信息内码为空");
		}
		
		JSONObject emp = currentLoginEmp.getCurrentEmpInfo();
		//提交流程
		if (StringUtils.isEmpty(procured.getTaskId())) {
			return Result.error("采购审批信息不完整");
		}
		FlowParam flowParam = new FlowParam();
		flowParam.setUserId(emp.getString("empNo"));
		
		flowParam.setTaskId(procured.getTaskId());
		if (!StringUtils.isEmpty(procured.getIsPass())) {
			Map<String, Object> variableMap = new HashMap<>();
			variableMap.put("isPass", procured.getIsPass());
			variableMap.put("link", procured.getLink());
			variableMap.put("userName", emp.getString("empName"));
			variableMap.put("userAvatar", emp.getString("profilePicture"));
			variableMap.put("userSign", emp.getString("nameSign"));
			BusinessContext businessContext = new BusinessContext();
			businessContext.put(WxWzProcured.class, procured);
			
			String currentNode = workflowService.getCurrentNode(procured.getTaskId());
			if((WxConstants.是.getCode().equals(procured.getIsPass()) && WxConstants.器材采购审批流程_最后审批节点名称.getCode().equals(currentNode)) ||(FlowConstants.flow_end_value.equals(procured.getLink()))) {
				//如果节信息是结束
				//或者最后一个环节，没有环节信息，并且是同意通过
				variableMap.put(WxConstants.流程监听器中执行的类.getCode(), "com.sdp.wx.controller.WxWzProcuredController");
				variableMap.put(WxConstants.流程监听器中执行类的方法.getCode(), "flowEndListener");
			}else {
				variableMap.put(WxConstants.流程监听器中执行的类.getCode(), "com.sdp.wx.controller.WxWzProcuredController");
				variableMap.put(WxConstants.流程监听器中执行类的方法.getCode(), "flowCommitListener");
			}
			variableMap.put(WxConstants.流程监听器中执行类的方法的参数.getCode(), businessContext);
			
			
			if (WxConstants.否.getCode().equals(procured.getIsPass())) {
				variableMap.put(FlowConstants.FLOW_ASSIGN_PERSON_KEY, procured.getApplicationEmpNo());
				if(StringUtils.isEmpty(procured.getApprovalOpinion())){
					procured.setApprovalOpinion("不同意");
				}
				procured.setApprovalState(WxConstants.流程审批状态_驳回.getCode());
			}else {
				if(StringUtils.isEmpty(procured.getApprovalOpinion()) && !WxConstants.器材采购审批流程_申报节点名称.getCode().equals(currentNode)){
					procured.setApprovalOpinion("同意");
				}
				variableMap.put(FlowConstants.FLOW_ASSIGN_PERSON_KEY, procured.getApprover());
				procured.setApprovalState(WxConstants.流程审批状态_审批中.getCode());
			}
			
			flowParam.setVariableMap(variableMap);
			
			//更新审批人列表
			if(!WxConstants.合同审批流程_申报节点名称.getCode().equals(currentNode)){
				procured.setApproversList((procured.getApproversList()==null?"":procured.getApproversList())+("["+emp.getString("empNo")+"]"));
			}
			
		
		}
		
		if (!StringUtils.isEmpty(procured.getApprovalOpinion())) {
			flowParam.setOpinion(procured.getApprovalOpinion());
		}
		iWxWzProcuredService.updateById(procured);
		workflowService.commitTask(flowParam);
		return Result.ok();
	}
	
	public void flowCommitListener(BusinessContext businessContext) {
		
	}
	
	/**
	 * 审批结束后，更改审批状态
	 * @param businessContext
	 */
	@Transactional(rollbackFor=Exception.class)
	public void flowEndListener(BusinessContext businessContext) {
		WxWzProcured procured = businessContext.get(WxWzProcured.class);
		if(procured!=null && WxConstants.是.getCode().equals(procured.getIsPass())) {
			procured.setApprovalState(WxConstants.流程审批状态_审批通过.getCode());
			iWxWzProcuredService.updateById(procured);
		}
	}
	
	/**
	 * 流程撤销
	 * @param instanceId
	 * @return
	 */
	@GetMapping(value = "/cancel")
	@Transactional(rollbackFor=Exception.class)
	public Result<?> cancel(@RequestParam(name="instanceId",required=true) String instanceId) {
		LambdaQueryWrapper<WxWzProcured> query = new LambdaQueryWrapper<>();
		query.eq(WxWzProcured::getInstanceId, instanceId);
		WxWzProcured procured = iWxWzProcuredService.getOne(query);
		if(procured==null) {
			return Result.error("采购信息不存在，不能进行撤销");
		}
		JSONObject emp = currentLoginEmp.getCurrentLoginInfo();
		if(!procured.getApplicationEmpNo().equals(emp.getString("empNo"))) {
			return Result.error("不是采购提交人，不能进行撤销操作");
		}
		
		//流程撤销
		workflowService.stopFlow(instanceId, "撤销");
		
		
		iWxWzProcuredService.removeById(procured.getKeyId());
		iWxWzProcuredDetailService.removeWxWzProcuredDetailByPlanCode(procured.getPlanCode());
		return Result.ok();
	}
	
	@RequestMapping(value="/queryByInstanceId")
	public Result<?> queryByInstanceId(@RequestParam String instanceId) {
		if (StringUtils.isEmpty(instanceId)) {
			return Result.error("instanceId不能为空!");
		}
		QueryWrapper<WxWzProcured> queryWrapper = new QueryWrapper<>();
		queryWrapper.lambda().eq(WxWzProcured::getInstanceId, instanceId);
		WxWzProcured procured = iWxWzProcuredService.getOne(queryWrapper, false);
		List<ActHiComment> commentList = workflowService.getApprovedOpinionNew(instanceId);
		procured.setApprovalOpinions(commentList);
		return Result.ok(procured);
	}
}

